Load the data and check its structure (variables, missing values, data types)

library(tidyverse)  
── Attaching core tidyverse packages ──────────────────────────────────────────────────────────────────────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.1.4     ✔ readr     2.1.5
✔ forcats   1.0.0     ✔ stringr   1.5.1
✔ ggplot2   3.5.1     ✔ tibble    3.2.1
✔ lubridate 1.9.4     ✔ tidyr     1.3.1
✔ purrr     1.0.4     ── Conflicts ────────────────────────────────────────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the ]8;;http://conflicted.r-lib.org/conflicted package]8;; to force all conflicts to become errors
library(here)       
here() starts at C:/Users/Lenovo/Documents/RStudioProjects/UFO-Sightings---R-Project
library(withr)      
ufo_sightings <- readr::read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/main/data/2023/2023-06-20/ufo_sightings.csv')
Rows: 96429 Columns: 12── Column specification ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr  (7): city, state, country_code, shape, reported_duration, summary, day_part
dbl  (1): duration_seconds
lgl  (1): has_images
dttm (2): reported_date_time, reported_date_time_utc
date (1): posted_date
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
places <- readr::read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/main/data/2023/2023-06-20/places.csv')
Rows: 14417 Columns: 10── Column specification ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (6): city, alternate_city_names, state, country, country_code, timezone
dbl (4): latitude, longitude, population, elevation_m
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
day_parts_map <- readr::read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/main/data/2023/2023-06-20/day_parts_map.csv')
Rows: 26409 Columns: 12── Column specification ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
dbl  (2): rounded_lat, rounded_long
date (1): rounded_date
time (9): astronomical_twilight_begin, nautical_twilight_begin, civil_twilight_begin, sunrise, solar_noon, sunset, civil_twilight_end, nauti...
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.

Checking if files have been loaded correctly

head(ufo_sightings)
head(places)
head(day_parts_map)

Saving data in respective files

dir.create(here("data", "2023", "2023-06-20"), recursive = TRUE, showWarnings = FALSE)

write_csv(ufo_sightings, here("data", "2023", "2023-06-20", "ufo_sightings.csv"))
write_csv(places, here("data", "2023", "2023-06-20", "places.csv"))
write_csv(day_parts_map, here("data", "2023", "2023-06-20", "day_parts_map.csv"))

Checking missing data

glimpse(ufo_sightings)
Rows: 96,429
Columns: 12
$ reported_date_time     <dttm> 2022-08-29 06:03:00, 2022-08-20 01:51:00, 2022-08-13 05:30:00, 2022-08-06 21:00:00, 2022-08-04 07:40:00, 2022-…
$ reported_date_time_utc <dttm> 2022-08-29 06:03:00, 2022-08-20 01:51:00, 2022-08-13 05:30:00, 2022-08-06 21:00:00, 2022-08-04 07:40:00, 2022-…
$ posted_date            <date> 2022-09-09, 2022-10-08, 2022-09-09, 2022-09-09, 2022-09-09, 2022-09-09, 2022-09-09, 2022-09-09, 2022-09-09, 20…
$ city                   <chr> "Pinehurst", "Rapid City", "Cleveland", "Bloomington", "Irvine", "Moore", "Short Pump", "Norwalk", "Blayney", "…
$ state                  <chr> "NC", "MI", "OH", "IN", "CA", "OK", "VA", "CT", "New South Wales", "WY", "NH", "AZ", "FL", "OR", "Haryana", "NM…
$ country_code           <chr> "US", "US", "US", "US", "US", "US", "US", "US", "AU", "US", "US", "US", "US", "US", "IN", "US", "US", "US", "US…
$ shape                  <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ reported_duration      <chr> "15 mins\u0085", "1 minute", "2 hours", "30 seconds", "3 minutes", "10 minutes", "20 seconds", "5 minutes", "90…
$ duration_seconds       <dbl> 900, 60, 172800, 30, 180, 600, 20, 300, 120, 1800, 10, 3, 45, 60, 240, 32, 300, 600, 180, 1200, 45, 300, 180, 1…
$ summary                <chr> "Saw multi color object above horizon.", "An object in the shape of a straight line about an inch from our view…
$ has_images             <lgl> FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,…
$ day_part               <chr> "night", "nautical dusk", "night", "afternoon", "night", "morning", "morning", "afternoon", NA, "astronomical d…
glimpse(places)
Rows: 14,417
Columns: 10
$ city                 <chr> "Pinehurst", "Rapid City", "Cleveland", "Bloomington", "Irvine", "Moore", "Short Pump", "Norwalk", "Blayney", "Gr…
$ alternate_city_names <chr> "Pajnkherst,bynhwrst,pynhwrst  karwlynay shmaly,Пајнхерст,بينهورست,پینهورست، کارولینای شمالی", NA, "CLE,Cleavelan…
$ state                <chr> "NC", "MI", "OH", "IN", "CA", "OK", "VA", "CT", "New South Wales", "WY", "NH", "AZ", "FL", "OR", "Haryana", "NM",…
$ country              <chr> "USA", "USA", "USA", "USA", "USA", "USA", "USA", "USA", "Australia", "USA", "USA", "USA", "USA", "USA", "India", …
$ country_code         <chr> "US", "US", "US", "US", "US", "US", "US", "US", "AU", "US", "US", "US", "US", "US", "IN", "US", "US", "US", "US",…
$ latitude             <dbl> 35.19543, 44.83445, 41.49950, 39.16533, 33.66946, 35.33951, 37.65042, 41.11760, -33.53233, 44.48912, 44.05368, 33…
$ longitude            <dbl> -79.46948, -85.28256, -81.69541, -86.52639, -117.82311, -97.48670, -77.61249, -73.40790, 149.25367, -108.05621, -…
$ timezone             <chr> "America/New_York", "America/Detroit", "America/New_York", "America/Indiana/Indianapolis", "America/Los_Angeles",…
$ population           <dbl> 15752, 1352, 388072, 84067, 256927, 60451, 24729, 88485, 3355, 1879, 2349, 1608139, 71579, 7912, 197340, 559121, …
$ elevation_m          <dbl> 160, 192, 199, 235, 17, 382, 89, 11, NA, 1156, 160, 331, 1, 157, NA, 1511, 414, 2, 393, 89, 1373, 264, 1, 89, 220…
glimpse(day_parts_map)
Rows: 26,409
Columns: 12
$ rounded_lat                 <dbl> 40, 40, 40, 40, 30, 40, 40, 40, -30, 40, 40, 30, 30, 40, 30, 40, 30, 30, 40, 30, 40, 30, 40, 30, 50, 40, 2…
$ rounded_long                <dbl> -80, -90, -80, -90, -120, -100, -80, -70, 150, -110, -70, -110, -80, -120, 80, -110, -120, -80, -100, -120…
$ rounded_date                <date> 2022-08-28, 2022-08-21, 2022-08-14, 2022-08-07, 2022-08-07, 2022-07-24, 2022-07-17, 2022-07-17, 2022-07-1…
$ astronomical_twilight_begin <time> 09:07:43, 09:38:33, 08:48:54, 09:19:00, 11:55:02, 09:39:05, 08:09:39, 07:29:37, 19:30:59, 10:01:25, 07:21…
$ nautical_twilight_begin     <time> 09:42:49, 10:14:53, 09:26:40, 09:58:23, 12:26:50, 10:22:03, 08:54:27, 08:14:25, 20:00:01, 10:47:51, 08:07…
$ civil_twilight_begin        <time> 10:16:18, 10:49:12, 10:01:56, 10:34:41, 12:57:22, 11:00:33, 09:34:01, 08:54:00, 20:29:37, 11:28:21, 08:48…
$ sunrise                     <time> 10:42:53, 11:16:15, 10:29:32, 11:02:53, 13:21:39, 11:30:01, 10:04:06, 09:24:04, 20:54:22, 11:58:55, 09:18…
$ solar_noon                  <time> 17:21:10, 18:03:05, 17:24:39, 18:05:45, 20:05:45, 18:46:32, 17:26:12, 16:46:12, 02:05:20, 19:25:26, 16:45…
$ sunset                      <time> 23:59:27, 00:49:55, 00:19:45, 01:08:37, 02:49:51, 02:03:03, 00:48:18, 00:08:20, 07:16:18, 02:51:58, 00:12…
$ civil_twilight_end          <time> 00:26:02, 01:16:58, 00:47:21, 01:36:50, 03:14:07, 02:32:31, 01:18:23, 00:38:24, 07:41:03, 03:22:32, 00:42…
$ nautical_twilight_end       <time> 00:59:31, 01:51:17, 01:22:37, 02:13:08, 03:44:39, 03:11:02, 01:57:57, 01:17:59, 08:10:40, 04:03:02, 01:23…
$ astronomical_twilight_end   <time> 01:34:37, 02:27:37, 02:00:24, 02:52:31, 04:16:27, 03:54:00, 02:42:45, 02:02:47, 08:39:42, 04:49:28, 02:09…
colSums(is.na(ufo_sightings))
    reported_date_time reported_date_time_utc            posted_date                   city                  state           country_code 
                     0                      0                      0                      0                     85                      0 
                 shape      reported_duration       duration_seconds                summary             has_images               day_part 
                  2039                      0                      0                     31                      0                   2563 
colSums(is.na(places))
                city alternate_city_names                state              country         country_code             latitude 
                   0                 2953                   32                    0                    0                    0 
           longitude             timezone           population          elevation_m 
                   0                    0                    0                 2285 
colSums(is.na(day_parts_map))
                rounded_lat                rounded_long                rounded_date astronomical_twilight_begin     nautical_twilight_begin 
                          0                           0                           0                         951                         122 
       civil_twilight_begin                     sunrise                  solar_noon                      sunset          civil_twilight_end 
                          2                           2                           0                           2                           2 
      nautical_twilight_end   astronomical_twilight_end 
                        122                         951 

Summary of the data

dim(ufo_sightings)
[1] 96429    12
summary(ufo_sightings)
 reported_date_time               reported_date_time_utc            posted_date             city              state          
 Min.   :1925-12-29 00:00:00.00   Min.   :1925-12-29 00:00:00.00   Min.   :1998-03-07   Length:96429       Length:96429      
 1st Qu.:2004-10-01 05:10:00.00   1st Qu.:2004-10-01 05:10:00.00   1st Qu.:2006-10-30   Class :character   Class :character  
 Median :2012-02-05 03:00:00.00   Median :2012-02-05 03:00:00.00   Median :2012-08-19   Mode  :character   Mode  :character  
 Mean   :2009-04-30 02:41:30.98   Mean   :2009-04-30 02:41:30.98   Mean   :2011-09-26                                        
 3rd Qu.:2016-01-25 03:30:00.00   3rd Qu.:2016-01-25 03:30:00.00   3rd Qu.:2016-07-15                                        
 Max.   :2023-05-18 19:27:00.00   Max.   :2023-05-18 19:27:00.00   Max.   :2023-05-19                                        
 country_code          shape           reported_duration  duration_seconds      summary          has_images        day_part        
 Length:96429       Length:96429       Length:96429       Min.   :0.000e+00   Length:96429       Mode :logical   Length:96429      
 Class :character   Class :character   Class :character   1st Qu.:3.000e+01   Class :character   FALSE:96429     Class :character  
 Mode  :character   Mode  :character   Mode  :character   Median :1.800e+02   Mode  :character                   Mode  :character  
                                                          Mean   :3.161e+04                                                        
                                                          3rd Qu.:6.000e+02                                                        
                                                          Max.   :1.987e+09                                                        
dim(places)
[1] 14417    10
summary(places)
     city           alternate_city_names    state             country          country_code          latitude        longitude      
 Length:14417       Length:14417         Length:14417       Length:14417       Length:14417       Min.   :-53.15   Min.   :-170.48  
 Class :character   Class :character     Class :character   Class :character   Class :character   1st Qu.: 34.99   1st Qu.: -95.46  
 Mode  :character   Mode  :character     Mode  :character   Mode  :character   Mode  :character   Median : 40.09   Median : -84.21  
                                                                                                  Mean   : 37.76   Mean   : -75.36  
                                                                                                  3rd Qu.: 42.96   3rd Qu.: -74.82  
                                                                                                  Max.   : 70.64   Max.   : 179.19  
                                                                                                                                    
   timezone           population        elevation_m    
 Length:14417       Min.   :       0   Min.   : -57.0  
 Class :character   1st Qu.:    1926   1st Qu.:  65.0  
 Mode  :character   Median :    6085   Median : 194.0  
                    Mean   :   86375   Mean   : 288.2  
                    3rd Qu.:   21993   3rd Qu.: 304.0  
                    Max.   :22315474   Max.   :3097.0  
                                       NA's   :2285    
dim(day_parts_map)
[1] 26409    12
summary(day_parts_map)
  rounded_lat      rounded_long      rounded_date        astronomical_twilight_begin nautical_twilight_begin civil_twilight_begin
 Min.   :-50.00   Min.   :-170.00   Min.   :1925-12-27   Length:26409                Length:26409            Length:26409        
 1st Qu.: 30.00   1st Qu.:-110.00   1st Qu.:1999-01-17   Class1:hms                  Class1:hms              Class1:hms          
 Median : 40.00   Median : -90.00   Median :2007-03-25   Class2:difftime             Class2:difftime         Class2:difftime     
 Mean   : 36.23   Mean   : -80.01   Mean   :2004-03-18   Mode  :numeric              Mode  :numeric          Mode  :numeric      
 3rd Qu.: 40.00   3rd Qu.: -80.00   3rd Qu.:2014-10-12                                                                           
 Max.   : 70.00   Max.   : 180.00   Max.   :2023-05-21                                                                           
   sunrise          solar_noon          sunset         civil_twilight_end nautical_twilight_end astronomical_twilight_end
 Length:26409      Length:26409      Length:26409      Length:26409       Length:26409          Length:26409             
 Class1:hms        Class1:hms        Class1:hms        Class1:hms         Class1:hms            Class1:hms               
 Class2:difftime   Class2:difftime   Class2:difftime   Class2:difftime    Class2:difftime       Class2:difftime          
 Mode  :numeric    Mode  :numeric    Mode  :numeric    Mode  :numeric     Mode  :numeric        Mode  :numeric           
                                                                                                                         
                                                                                                                         
sum(duplicated(ufo_sightings))
[1] 3

Handle missing observations (fill in or remove them), correct errors, etc.

Due to the large size of the file on which the analysis is performed, only some of the data was used for visual representation.

library(tidyverse)  
library(here)       
library(withr)
library(naniar)

UFO sightings

ufo_sightings %>% 
  dplyr::slice_sample(n = 1000) %>% 
  vis_miss(cluster = TRUE, sort_miss = TRUE)

Replacing missing data with most frequent entry and saving cleaned data

most_common_day_part <- ufo_sightings %>%
  count(day_part) %>%
  arrange(desc(n)) %>%
  slice(1) %>%
  pull(day_part)

most_common_shape <- ufo_sightings %>%
  count(shape) %>%
  arrange(desc(n)) %>%
  slice(1) %>%
  pull(shape)

# najczestrza wartosc
ufo_clean <- ufo_sightings %>%
  mutate(
    day_part = ifelse(is.na(day_part), most_common_day_part, day_part),
    shape = ifelse(is.na(shape), most_common_shape, shape)
  )

write_csv(ufo_clean, here("data", "2023", "2023-06-20", "ufo_clean.csv"))
ufo_clean %>% 
  dplyr::slice_sample(n = 1000) %>% 
  vis_miss(cluster = TRUE, sort_miss = TRUE)

Places

places %>% 
  dplyr::slice_sample(n = 1000) %>% 
  vis_miss(cluster = TRUE, sort_miss = TRUE)

Replacing missing city name with empty string, elevation with mean value and saving cleaned data

#nie mam lepszego pomysłu na uzuepłenienie niż " "
places_clean <- places %>%
  mutate(
    alternate_city_names = ifelse(is.na(alternate_city_names), " ", alternate_city_names)
  )

median_elevation <- median(places$elevation_m, na.rm = TRUE)

places_clean <- places_clean %>%
  mutate(
    elevation_m = ifelse(is.na(elevation_m), median_elevation, elevation_m)
  )

write_csv(places_clean, here("data", "2023", "2023-06-20", "places_clean.csv"))
places_clean %>% 
  dplyr::slice_sample(n = 1000) %>% 
  vis_miss(cluster = TRUE, sort_miss = TRUE)

Day parts map

day_parts_map %>% 
  dplyr::slice_sample(n = 1000) %>% 
  vis_miss(cluster = TRUE, sort_miss = TRUE)

Replacing missing data with mean value and saving cleaned data

day_parts_clean <- day_parts_map %>%
  mutate(
    astronomical_twilight_begin = ifelse(
      is.na(astronomical_twilight_begin),
      median(astronomical_twilight_begin, na.rm = TRUE),
      astronomical_twilight_begin
    ),
    astronomical_twilight_end = ifelse(
      is.na(astronomical_twilight_end),
      median(astronomical_twilight_end, na.rm = TRUE),
      astronomical_twilight_end
    )
  )

write_csv(day_parts_clean, here("data", "2023", "2023-06-20", "day_parts_clean.csv"))
day_parts_clean %>% 
  dplyr::slice_sample(n = 1000) %>% 
  vis_miss(cluster = TRUE, sort_miss = TRUE)

Adjust the data format to meet the requirements of your analysis


ufo_model_data <- ufo_clean %>%
  filter(!is.na(shape), !is.na(reported_duration), !is.na(summary))


places_model_data <- places_clean %>%
  filter(!is.na(alternate_city_names))
glimpse(ufo_model_data)
Rows: 96,398
Columns: 12
$ reported_date_time     <dttm> 2022-08-29 06:03:00, 2022-08-20 01:51:00, 2022-08-13 05:30:00, 2022-08-06 21:00:00, 2022-08-04 07:40:00, 2022-07-22 16:00:00, 2022-07-19 16…
$ reported_date_time_utc <dttm> 2022-08-29 06:03:00, 2022-08-20 01:51:00, 2022-08-13 05:30:00, 2022-08-06 21:00:00, 2022-08-04 07:40:00, 2022-07-22 16:00:00, 2022-07-19 16…
$ posted_date            <date> 2022-09-09, 2022-10-08, 2022-09-09, 2022-09-09, 2022-09-09, 2022-09-09, 2022-09-09, 2022-09-09, 2022-09-09, 2022-09-09, 2022-09-09, 2022-09…
$ city                   <chr> "Pinehurst", "Rapid City", "Cleveland", "Bloomington", "Irvine", "Moore", "Short Pump", "Norwalk", "Blayney", "Greybull", "North Conway", "P…
$ state                  <chr> "NC", "MI", "OH", "IN", "CA", "OK", "VA", "CT", "New South Wales", "WY", "NH", "AZ", "FL", "OR", "Haryana", "NM", "CA", "NC", "OK", "CA", "N…
$ country_code           <chr> "US", "US", "US", "US", "US", "US", "US", "US", "AU", "US", "US", "US", "US", "US", "IN", "US", "US", "US", "US", "US", "US", "US", "US", "U…
$ shape                  <chr> "light", "light", "light", "light", "light", "light", "light", "light", "light", "light", "light", "light", "light", "light", "light", "ligh…
$ reported_duration      <chr> "15 mins\u0085", "1 minute", "2 hours", "30 seconds", "3 minutes", "10 minutes", "20 seconds", "5 minutes", "90 - 120 seconds", "20-30 minut…
$ duration_seconds       <dbl> 900, 60, 172800, 30, 180, 600, 20, 300, 120, 1800, 10, 3, 45, 60, 240, 32, 300, 600, 180, 1200, 45, 300, 180, 1200, 300, 7200, 47, 1800, 180…
$ summary                <chr> "Saw multi color object above horizon.", "An object in the shape of a straight line about an inch from our viewing area moving slowly across…
$ has_images             <lgl> FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, …
$ day_part               <chr> "night", "nautical dusk", "night", "afternoon", "night", "morning", "morning", "afternoon", "night", "astronomical dusk", "afternoon", "morn…
glimpse(places_model_data)
Rows: 14,417
Columns: 10
$ city                 <chr> "Pinehurst", "Rapid City", "Cleveland", "Bloomington", "Irvine", "Moore", "Short Pump", "Norwalk", "Blayney", "Greybull", "North Conway", "Pho…
$ alternate_city_names <chr> "Pajnkherst,bynhwrst,pynhwrst  karwlynay shmaly,Пајнхерст,بينهورست,پینهورست، کارولینای شمالی", " ", "CLE,Cleaveland,Cleveland,Forest City,Klev…
$ state                <chr> "NC", "MI", "OH", "IN", "CA", "OK", "VA", "CT", "New South Wales", "WY", "NH", "AZ", "FL", "OR", "Haryana", "NM", "CA", "NC", "OK", "CA", "NV"…
$ country              <chr> "USA", "USA", "USA", "USA", "USA", "USA", "USA", "USA", "Australia", "USA", "USA", "USA", "USA", "USA", "India", "USA", "USA", "USA", "USA", "…
$ country_code         <chr> "US", "US", "US", "US", "US", "US", "US", "US", "AU", "US", "US", "US", "US", "US", "IN", "US", "US", "US", "US", "US", "US", "US", "US", "US"…
$ latitude             <dbl> 35.19543, 44.83445, 41.49950, 39.16533, 33.66946, 35.33951, 37.65042, 41.11760, -33.53233, 44.48912, 44.05368, 33.44838, 26.14036, 43.39012, 2…
$ longitude            <dbl> -79.46948, -85.28256, -81.69541, -86.52639, -117.82311, -97.48670, -77.61249, -73.40790, 149.25367, -108.05621, -71.12840, -112.07404, -80.213…
$ timezone             <chr> "America/New_York", "America/Detroit", "America/New_York", "America/Indiana/Indianapolis", "America/Los_Angeles", "America/Chicago", "America/…
$ population           <dbl> 15752, 1352, 388072, 84067, 256927, 60451, 24729, 88485, 3355, 1879, 2349, 1608139, 71579, 7912, 197340, 559121, 71035, 6137, 25892, 3898747, …
$ elevation_m          <dbl> 160, 192, 199, 235, 17, 382, 89, 11, 194, 1156, 160, 331, 1, 157, 194, 1511, 414, 2, 393, 89, 1373, 264, 1, 89, 220, 287, 798, 219, 8, 1820, 5…
glimpse(day_parts_clean)
Rows: 26,409
Columns: 12
$ rounded_lat                 <dbl> 40, 40, 40, 40, 30, 40, 40, 40, -30, 40, 40, 30, 30, 40, 30, 40, 30, 30, 40, 30, 40, 30, 40, 30, 50, 40, 20, 30, 30, 30, 30, 30, 30, 30…
$ rounded_long                <dbl> -80, -90, -80, -90, -120, -100, -80, -70, 150, -110, -70, -110, -80, -120, 80, -110, -120, -80, -100, -120, -120, -120, -80, -80, -120,…
$ rounded_date                <date> 2022-08-28, 2022-08-21, 2022-08-14, 2022-08-07, 2022-08-07, 2022-07-24, 2022-07-17, 2022-07-17, 2022-07-10, 2022-07-10, 2022-07-10, 20…
$ astronomical_twilight_begin <dbl> 32863, 34713, 31734, 33540, 42902, 34745, 29379, 26977, 70259, 36085, 26478, 39124, 31660, 38079, 79348, 35471, 40996, 31561, 33859, 41…
$ nautical_twilight_begin     <time> 09:42:49, 10:14:53, 09:26:40, 09:58:23, 12:26:50, 10:22:03, 08:54:27, 08:14:25, 20:00:01, 10:47:51, 08:07:45, 11:26:57, 09:23:03, 11:2…
$ civil_twilight_begin        <time> 10:16:18, 10:49:12, 10:01:56, 10:34:41, 12:57:22, 11:00:33, 09:34:01, 08:54:00, 20:29:37, 11:28:21, 08:48:15, 11:59:43, 09:56:11, 12:0…
$ sunrise                     <time> 10:42:53, 11:16:15, 10:29:32, 11:02:53, 13:21:39, 11:30:01, 10:04:06, 09:24:04, 20:54:22, 11:58:55, 09:18:51, 12:25:25, 10:22:07, 12:3…
$ solar_noon                  <time> 17:21:10, 18:03:05, 17:24:39, 18:05:45, 20:05:45, 18:46:32, 17:26:12, 16:46:12, 02:05:20, 19:25:26, 16:45:26, 19:25:26, 17:24:18, 20:0…
$ sunset                      <time> 23:59:27, 00:49:55, 00:19:45, 01:08:37, 02:49:51, 02:03:03, 00:48:18, 00:08:20, 07:16:18, 02:51:58, 00:12:00, 02:25:28, 00:26:29, 03:3…
$ civil_twilight_end          <time> 00:26:02, 01:16:58, 00:47:21, 01:36:50, 03:14:07, 02:32:31, 01:18:23, 00:38:24, 07:41:03, 03:22:32, 00:42:36, 02:51:10, 00:52:25, 04:0…
$ nautical_twilight_end       <time> 00:59:31, 01:51:17, 01:22:37, 02:13:08, 03:44:39, 03:11:02, 01:57:57, 01:17:59, 08:10:40, 04:03:02, 01:23:06, 03:23:56, 01:25:33, 04:4…
$ astronomical_twilight_end   <dbl> 5677, 8857, 7224, 10351, 15387, 14040, 9765, 7367, 31182, 17368, 7773, 14329, 7256, 20039, 55211, 17157, 16433, 6532, 13744, 15427, 179…
write_csv(ufo_model_data, here("data", "2023", "2023-06-20", "ufo_model_data.csv"))
write_csv(places_model_data, here("data", "2023", "2023-06-20", "places_model_data.csv"))

Add new columns to each dataframe

library(lubridate)
library(dplyr)
library(hms)

Dołączanie pakietu: ‘hms’

Następujący obiekt został zakryty z ‘package:lubridate’:

    hms

Adding new columns to “sightings” dataframe

ufo_model_data_mutated <- ufo_model_data %>%
  mutate(
    year = year(reported_date_time),
    month = month(reported_date_time),
    weekday = wday(reported_date_time, label = TRUE, abbr = FALSE, locale = "C"),
    is_weekend = weekday %in% c("Sat", "Sun"),
    country_upper = toupper(country_code),
    report_hour = hour(reported_date_time),
    city_state = paste(city, state, sep = ", "),
    report_delay_days = as.numeric(difftime(posted_date, as.Date(reported_date_time), units = "days"))
  )

ufo_model_data_mutated

Adding new columns to “places” dataframe

places_model_data_mutated <- places_model_data %>%
  mutate(
    city_state = paste(city, state, sep = ", "),
    is_us = country_code == "US",
    population_log = log1p(population),
    hemisphere = ifelse(latitude >= 0, "Northern", "Southern"),
    is_coastal = abs(longitude) < 80 | abs(longitude) > 120,
    pop_category = case_when(
      population < 10000 ~ "small",
      population < 100000 ~ "medium",
      TRUE ~ "large"
    ),
    elevation_category = case_when(
      is.na(elevation_m) ~ "unknown",
      elevation_m < 100 ~ "low",
      elevation_m < 500 ~ "medium",
      TRUE ~ "high"
    ),
    name_length = nchar(city),
    timezone_area = sapply(strsplit(timezone, "/"), `[`, 2)
  )

places_model_data_mutated

Adding new columns to “day parts” dataframe

day_parts_model_mutated <- day_parts_clean %>%
  mutate(
    daylight_duration = as.numeric(sunset - sunrise, units = "secs"),
    is_northern_hemisphere = rounded_lat >= 0,
    sunrise_hour = hour(sunrise),
    sunset_hour = hour(sunset),
    is_day_short = daylight_duration < 36000, # mniej niż 10h
    twilight_duration = as.numeric(astronomical_twilight_end - astronomical_twilight_begin, units = "secs"),
    is_long_twilight = twilight_duration > 5400, # 1.5h
    sunrise_minutes = hour(sunrise) * 60 + minute(sunrise),
    solar_noon_minutes = hour(solar_noon) * 60 + minute(solar_noon),
    sunset_minutes = hour(sunset) * 60 + minute(sunset)
  )

day_parts_model_mutated
glimpse(ufo_model_data_mutated)
Rows: 96,398
Columns: 20
$ reported_date_time     <dttm> 2022-08-29 06:03:00, 2022-08-20 01:51:00, 2022-08-13 05:30:00, 2022-08-06 21:00:00, 2022-08-04 07:40:00, 2022-07-22 16:00:00, 2022-07-19 16…
$ reported_date_time_utc <dttm> 2022-08-29 06:03:00, 2022-08-20 01:51:00, 2022-08-13 05:30:00, 2022-08-06 21:00:00, 2022-08-04 07:40:00, 2022-07-22 16:00:00, 2022-07-19 16…
$ posted_date            <date> 2022-09-09, 2022-10-08, 2022-09-09, 2022-09-09, 2022-09-09, 2022-09-09, 2022-09-09, 2022-09-09, 2022-09-09, 2022-09-09, 2022-09-09, 2022-09…
$ city                   <chr> "Pinehurst", "Rapid City", "Cleveland", "Bloomington", "Irvine", "Moore", "Short Pump", "Norwalk", "Blayney", "Greybull", "North Conway", "P…
$ state                  <chr> "NC", "MI", "OH", "IN", "CA", "OK", "VA", "CT", "New South Wales", "WY", "NH", "AZ", "FL", "OR", "Haryana", "NM", "CA", "NC", "OK", "CA", "N…
$ country_code           <chr> "US", "US", "US", "US", "US", "US", "US", "US", "AU", "US", "US", "US", "US", "US", "IN", "US", "US", "US", "US", "US", "US", "US", "US", "U…
$ shape                  <chr> "light", "light", "light", "light", "light", "light", "light", "light", "light", "light", "light", "light", "light", "light", "light", "ligh…
$ reported_duration      <chr> "15 mins\u0085", "1 minute", "2 hours", "30 seconds", "3 minutes", "10 minutes", "20 seconds", "5 minutes", "90 - 120 seconds", "20-30 minut…
$ duration_seconds       <dbl> 900, 60, 172800, 30, 180, 600, 20, 300, 120, 1800, 10, 3, 45, 60, 240, 32, 300, 600, 180, 1200, 45, 300, 180, 1200, 300, 7200, 47, 1800, 180…
$ summary                <chr> "Saw multi color object above horizon.", "An object in the shape of a straight line about an inch from our viewing area moving slowly across…
$ has_images             <lgl> FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, …
$ day_part               <chr> "night", "nautical dusk", "night", "afternoon", "night", "morning", "morning", "afternoon", "night", "astronomical dusk", "afternoon", "morn…
$ year                   <dbl> 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 20…
$ month                  <dbl> 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 5, 5, 5, 5, 5, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 1, 1, 1, 12, 12, 11, 11…
$ weekday                <ord> Monday, Saturday, Saturday, Saturday, Thursday, Friday, Tuesday, Thursday, Wednesday, Wednesday, Friday, Thursday, Tuesday, Saturday, Friday…
$ is_weekend             <lgl> FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, …
$ country_upper          <chr> "US", "US", "US", "US", "US", "US", "US", "US", "AU", "US", "US", "US", "US", "US", "IN", "US", "US", "US", "US", "US", "US", "US", "US", "U…
$ report_hour            <int> 6, 1, 5, 21, 7, 16, 16, 18, 19, 4, 0, 16, 2, 16, 17, 2, 22, 20, 2, 23, 6, 9, 1, 2, 12, 1, 6, 2, 2, 7, 20, 22, 1, 2, 23, 5, 1, 0, 0, 4, 0, 4,…
$ city_state             <chr> "Pinehurst, NC", "Rapid City, MI", "Cleveland, OH", "Bloomington, IN", "Irvine, CA", "Moore, OK", "Short Pump, VA", "Norwalk, CT", "Blayney,…
$ report_delay_days      <dbl> 11, 49, 27, 34, 36, 49, 52, 57, 58, 58, 63, 64, 66, 69, 5, 15, 17, 23, 32, 35, 38, 30, 0, 67, 7, 13, 22, 24, 24, 29, 31, 181, 45, 46, 91, 8,…
glimpse(places_model_data_mutated)
Rows: 14,417
Columns: 19
$ city                 <chr> "Pinehurst", "Rapid City", "Cleveland", "Bloomington", "Irvine", "Moore", "Short Pump", "Norwalk", "Blayney", "Greybull", "North Conway", "Pho…
$ alternate_city_names <chr> "Pajnkherst,bynhwrst,pynhwrst  karwlynay shmaly,Пајнхерст,بينهورست,پینهورست، کارولینای شمالی", " ", "CLE,Cleaveland,Cleveland,Forest City,Klev…
$ state                <chr> "NC", "MI", "OH", "IN", "CA", "OK", "VA", "CT", "New South Wales", "WY", "NH", "AZ", "FL", "OR", "Haryana", "NM", "CA", "NC", "OK", "CA", "NV"…
$ country              <chr> "USA", "USA", "USA", "USA", "USA", "USA", "USA", "USA", "Australia", "USA", "USA", "USA", "USA", "USA", "India", "USA", "USA", "USA", "USA", "…
$ country_code         <chr> "US", "US", "US", "US", "US", "US", "US", "US", "AU", "US", "US", "US", "US", "US", "IN", "US", "US", "US", "US", "US", "US", "US", "US", "US"…
$ latitude             <dbl> 35.19543, 44.83445, 41.49950, 39.16533, 33.66946, 35.33951, 37.65042, 41.11760, -33.53233, 44.48912, 44.05368, 33.44838, 26.14036, 43.39012, 2…
$ longitude            <dbl> -79.46948, -85.28256, -81.69541, -86.52639, -117.82311, -97.48670, -77.61249, -73.40790, 149.25367, -108.05621, -71.12840, -112.07404, -80.213…
$ timezone             <chr> "America/New_York", "America/Detroit", "America/New_York", "America/Indiana/Indianapolis", "America/Los_Angeles", "America/Chicago", "America/…
$ population           <dbl> 15752, 1352, 388072, 84067, 256927, 60451, 24729, 88485, 3355, 1879, 2349, 1608139, 71579, 7912, 197340, 559121, 71035, 6137, 25892, 3898747, …
$ elevation_m          <dbl> 160, 192, 199, 235, 17, 382, 89, 11, 194, 1156, 160, 331, 1, 157, 194, 1511, 414, 2, 393, 89, 1373, 264, 1, 89, 220, 287, 798, 219, 8, 1820, 5…
$ city_state           <chr> "Pinehurst, NC", "Rapid City, MI", "Cleveland, OH", "Bloomington, IN", "Irvine, CA", "Moore, OK", "Short Pump, VA", "Norwalk, CT", "Blayney, N…
$ is_us                <lgl> TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TR…
$ population_log       <dbl> 9.664786, 7.210080, 12.868949, 11.339381, 12.456551, 11.009605, 10.115772, 11.390600, 8.118505, 7.539027, 7.762171, 14.290589, 11.178571, 8.97…
$ hemisphere           <chr> "Northern", "Northern", "Northern", "Northern", "Northern", "Northern", "Northern", "Northern", "Southern", "Northern", "Northern", "Northern"…
$ is_coastal           <lgl> TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FAL…
$ pop_category         <chr> "medium", "small", "large", "medium", "large", "medium", "medium", "medium", "small", "small", "small", "large", "medium", "small", "large", "…
$ elevation_category   <chr> "medium", "medium", "medium", "medium", "low", "medium", "low", "low", "medium", "high", "medium", "medium", "low", "medium", "medium", "high"…
$ name_length          <int> 9, 10, 9, 11, 6, 5, 10, 7, 7, 8, 12, 7, 10, 9, 7, 11, 8, 14, 5, 11, 4, 5, 14, 13, 5, 7, 10, 7, 7, 7, 12, 5, 10, 9, 6, 10, 12, 6, 7, 7, 12, 9, …
$ timezone_area        <chr> "New_York", "Detroit", "New_York", "Indiana", "Los_Angeles", "Chicago", "New_York", "New_York", "Sydney", "Denver", "New_York", "Phoenix", "Ne…
glimpse(day_parts_clean)
Rows: 26,409
Columns: 12
$ rounded_lat                 <dbl> 40, 40, 40, 40, 30, 40, 40, 40, -30, 40, 40, 30, 30, 40, 30, 40, 30, 30, 40, 30, 40, 30, 40, 30, 50, 40, 20, 30, 30, 30, 30, 30, 30, 30…
$ rounded_long                <dbl> -80, -90, -80, -90, -120, -100, -80, -70, 150, -110, -70, -110, -80, -120, 80, -110, -120, -80, -100, -120, -120, -120, -80, -80, -120,…
$ rounded_date                <date> 2022-08-28, 2022-08-21, 2022-08-14, 2022-08-07, 2022-08-07, 2022-07-24, 2022-07-17, 2022-07-17, 2022-07-10, 2022-07-10, 2022-07-10, 20…
$ astronomical_twilight_begin <dbl> 32863, 34713, 31734, 33540, 42902, 34745, 29379, 26977, 70259, 36085, 26478, 39124, 31660, 38079, 79348, 35471, 40996, 31561, 33859, 41…
$ nautical_twilight_begin     <time> 09:42:49, 10:14:53, 09:26:40, 09:58:23, 12:26:50, 10:22:03, 08:54:27, 08:14:25, 20:00:01, 10:47:51, 08:07:45, 11:26:57, 09:23:03, 11:2…
$ civil_twilight_begin        <time> 10:16:18, 10:49:12, 10:01:56, 10:34:41, 12:57:22, 11:00:33, 09:34:01, 08:54:00, 20:29:37, 11:28:21, 08:48:15, 11:59:43, 09:56:11, 12:0…
$ sunrise                     <time> 10:42:53, 11:16:15, 10:29:32, 11:02:53, 13:21:39, 11:30:01, 10:04:06, 09:24:04, 20:54:22, 11:58:55, 09:18:51, 12:25:25, 10:22:07, 12:3…
$ solar_noon                  <time> 17:21:10, 18:03:05, 17:24:39, 18:05:45, 20:05:45, 18:46:32, 17:26:12, 16:46:12, 02:05:20, 19:25:26, 16:45:26, 19:25:26, 17:24:18, 20:0…
$ sunset                      <time> 23:59:27, 00:49:55, 00:19:45, 01:08:37, 02:49:51, 02:03:03, 00:48:18, 00:08:20, 07:16:18, 02:51:58, 00:12:00, 02:25:28, 00:26:29, 03:3…
$ civil_twilight_end          <time> 00:26:02, 01:16:58, 00:47:21, 01:36:50, 03:14:07, 02:32:31, 01:18:23, 00:38:24, 07:41:03, 03:22:32, 00:42:36, 02:51:10, 00:52:25, 04:0…
$ nautical_twilight_end       <time> 00:59:31, 01:51:17, 01:22:37, 02:13:08, 03:44:39, 03:11:02, 01:57:57, 01:17:59, 08:10:40, 04:03:02, 01:23:06, 03:23:56, 01:25:33, 04:4…
$ astronomical_twilight_end   <dbl> 5677, 8857, 7224, 10351, 15387, 14040, 9765, 7367, 31182, 17368, 7773, 14329, 7256, 20039, 55211, 17157, 16433, 6532, 13744, 15427, 179…

Explore data with charts

library(ggplot2)
library(dplyr)
library(sf)
Linking to GEOS 3.13.0, GDAL 3.10.1, PROJ 9.5.1; sf_use_s2() is TRUE
library(rnaturalearth)
library(rnaturalearthdata)

Dołączanie pakietu: ‘rnaturalearthdata’

Następujący obiekt został zakryty z ‘package:rnaturalearth’:

    countries110

Number of sightings per day

ufo_model_data_mutated %>%
  count(date = as.Date(reported_date_time)) %>%
  ggplot(aes(x = date, y = n)) +
  geom_line(color = "steelblue") +
  labs(title = "Number of sightings per day", x = "Date", y = "Number of sightings")

Number of sightings depending on the day of the week

ufo_model_data_mutated %>%
  count(weekday) %>%
  ggplot(aes(x = weekday, y = n)) +
  geom_col(fill = "orange") +
  labs(title = "Sightings depending on the day of the week", x = "Day of the week", y = "Number of sightings")

Hourly distribution of sightings

ufo_model_data_mutated %>%
  mutate(hour = hour(reported_date_time)) %>%
  count(hour) %>%
  ggplot(aes(x = hour, y = n)) +
  geom_col(fill = "purple") +
  labs(title = "Hourly distribution of sightings", x = "Hour of the day", y = "Number of sightings")

Heatmap: day of the week vs hour of the day

ufo_model_data_mutated %>%
  mutate(
    hour = hour(reported_date_time),
    weekday = fct_relevel(weekday, c("Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"))
  ) %>%
  count(weekday, hour) %>%
  ggplot(aes(x = hour, y = weekday, fill = n)) +
  geom_tile(color = "white") +
  scale_fill_viridis_c() +
  labs(title = "Heatmap: day of the week vs hour of the day", x = "Hour of the day", y = "Day of the week", fill = "Number of sightings")
Ostrzeżenie: There was 1 warning in `mutate()`.
ℹ In argument: `weekday = fct_relevel(...)`.
Caused by warning:
! 7 unknown levels in `f`: Mon, Tue, Wed, Thu, Fri, Sat, and Sun

ufo_model_data_mutated %>%
  mutate(image_status = ifelse(has_images, "Has an image", "Has no image")) %>%
  count(image_status) %>%
  ggplot(aes(x = "", y = n, fill = image_status)) +
  geom_col(width = 1) +
  coord_polar(theta = "y") +
  labs(title = "Sightins with images vs no image", fill = "Image existence") +
  theme_void() +
  scale_fill_manual(values = c("Has an image" = "#66BB6A", "Has no image" = "#EF5350"))

Making sure if above piechart is correct

sum(ufo_model_data_mutated$has_images != FALSE, na.rm = TRUE)
[1] 0

Number of sightings per shape

ufo_model_data_mutated %>%
  count(shape) %>%
  ggplot(aes(x = reorder(shape, n), y = n)) +
  geom_col(fill = "skyblue") +
  coord_flip() +
  labs(title = "Number of sightings per shape", x = "Shape", y = "Number of sightings")

Number of sightings per country

ufo_model_data_mutated %>%
  count(country_code) %>%
  filter(n >= 100) %>%
  ggplot(aes(x = reorder(country_code, n), y = n)) +
  geom_bar(stat = "identity", fill = "skyblue") +
  labs(
    title = "Number of sightings per country",
    x = "Country code",
    y = "Number of sightings"
  ) +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Density map of sightings

world <- ne_countries(scale = "medium", returnclass = "sf")

places_clean %>%
  filter(!is.na(latitude), !is.na(longitude)) %>%
  mutate(
    pop_category = case_when(
      population < 10000  ~ "small",
      population < 100000 ~ "medium",
      TRUE                ~ "large"
    )
  ) %>%
  ggplot() +
  geom_sf(data = world, fill = "lightgray", color = "black") +  # Dodajemy mapę
  geom_point(aes(
    x = longitude, y = latitude,
    size = population, color = pop_category
  ), alpha = 0.6) +
  scale_size(range = c(1, 6), guide = "none") +
  labs(
    title = "Cities with UFO sightings",
    subtitle = "Point size ~ population, color ~ population category",
    x = "Latitude",
    y = "Altitude",
    color = "Population category"
  ) +
  theme_minimal()

LS0tDQp0aXRsZTogIkV4cGxvcmF0b3J5IERhdGEgQW5hbGFzeXMgd2l0aCBVRk8gc2lnbmFscyBkYXRhc2V0Ig0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCg0KIyBMb2FkIHRoZSBkYXRhIGFuZCBjaGVjayBpdHMgc3RydWN0dXJlICh2YXJpYWJsZXMsIG1pc3NpbmcgdmFsdWVzLCBkYXRhIHR5cGVzKQ0KDQpgYGB7cn0NCmxpYnJhcnkodGlkeXZlcnNlKSAgDQpsaWJyYXJ5KGhlcmUpICAgICAgIA0KbGlicmFyeSh3aXRocikgICAgICANCmBgYA0KDQpgYGB7cn0NCnVmb19zaWdodGluZ3MgPC0gcmVhZHI6OnJlYWRfY3N2KCdodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vcmZvcmRhdGFzY2llbmNlL3RpZHl0dWVzZGF5L21haW4vZGF0YS8yMDIzLzIwMjMtMDYtMjAvdWZvX3NpZ2h0aW5ncy5jc3YnKQ0KcGxhY2VzIDwtIHJlYWRyOjpyZWFkX2NzdignaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3Jmb3JkYXRhc2NpZW5jZS90aWR5dHVlc2RheS9tYWluL2RhdGEvMjAyMy8yMDIzLTA2LTIwL3BsYWNlcy5jc3YnKQ0KZGF5X3BhcnRzX21hcCA8LSByZWFkcjo6cmVhZF9jc3YoJ2h0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9yZm9yZGF0YXNjaWVuY2UvdGlkeXR1ZXNkYXkvbWFpbi9kYXRhLzIwMjMvMjAyMy0wNi0yMC9kYXlfcGFydHNfbWFwLmNzdicpDQoNCmBgYA0KDQpDaGVja2luZyBpZiBmaWxlcyBoYXZlIGJlZW4gbG9hZGVkIGNvcnJlY3RseQ0KDQpgYGB7cn0NCmhlYWQodWZvX3NpZ2h0aW5ncykNCmhlYWQocGxhY2VzKQ0KaGVhZChkYXlfcGFydHNfbWFwKQ0KYGBgDQoNClNhdmluZyBkYXRhIGluIHJlc3BlY3RpdmUgZmlsZXMNCg0KYGBge3J9DQpkaXIuY3JlYXRlKGhlcmUoImRhdGEiLCAiMjAyMyIsICIyMDIzLTA2LTIwIiksIHJlY3Vyc2l2ZSA9IFRSVUUsIHNob3dXYXJuaW5ncyA9IEZBTFNFKQ0KDQp3cml0ZV9jc3YodWZvX3NpZ2h0aW5ncywgaGVyZSgiZGF0YSIsICIyMDIzIiwgIjIwMjMtMDYtMjAiLCAidWZvX3NpZ2h0aW5ncy5jc3YiKSkNCndyaXRlX2NzdihwbGFjZXMsIGhlcmUoImRhdGEiLCAiMjAyMyIsICIyMDIzLTA2LTIwIiwgInBsYWNlcy5jc3YiKSkNCndyaXRlX2NzdihkYXlfcGFydHNfbWFwLCBoZXJlKCJkYXRhIiwgIjIwMjMiLCAiMjAyMy0wNi0yMCIsICJkYXlfcGFydHNfbWFwLmNzdiIpKQ0KYGBgDQoNCkNoZWNraW5nIG1pc3NpbmcgZGF0YQ0KDQpgYGB7cn0NCmdsaW1wc2UodWZvX3NpZ2h0aW5ncykNCmdsaW1wc2UocGxhY2VzKQ0KZ2xpbXBzZShkYXlfcGFydHNfbWFwKQ0KYGBgDQoNCmBgYHtyfQ0KY29sU3Vtcyhpcy5uYSh1Zm9fc2lnaHRpbmdzKSkNCmBgYA0KDQpgYGB7cn0NCmNvbFN1bXMoaXMubmEocGxhY2VzKSkNCmBgYA0KDQpgYGB7cn0NCmNvbFN1bXMoaXMubmEoZGF5X3BhcnRzX21hcCkpDQpgYGANCg0KU3VtbWFyeSBvZiB0aGUgZGF0YQ0KDQpgYGB7cn0NCmRpbSh1Zm9fc2lnaHRpbmdzKQ0Kc3VtbWFyeSh1Zm9fc2lnaHRpbmdzKQ0KYGBgDQoNCmBgYHtyfQ0KZGltKHBsYWNlcykNCnN1bW1hcnkocGxhY2VzKQ0KYGBgDQoNCmBgYHtyfQ0KZGltKGRheV9wYXJ0c19tYXApDQpzdW1tYXJ5KGRheV9wYXJ0c19tYXApDQpgYGANCg0KYGBge3J9DQpzdW0oZHVwbGljYXRlZCh1Zm9fc2lnaHRpbmdzKSkNCmBgYA0KDQojIEhhbmRsZSBtaXNzaW5nIG9ic2VydmF0aW9ucyAoZmlsbCBpbiBvciByZW1vdmUgdGhlbSksIGNvcnJlY3QgZXJyb3JzLCBldGMuDQoNCkR1ZSB0byB0aGUgbGFyZ2Ugc2l6ZSBvZiB0aGUgZmlsZSBvbiB3aGljaCB0aGUgYW5hbHlzaXMgaXMgcGVyZm9ybWVkLCBvbmx5IHNvbWUgb2YgdGhlIGRhdGEgd2FzIHVzZWQgZm9yIHZpc3VhbCByZXByZXNlbnRhdGlvbi4NCg0KYGBge3J9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkgIA0KbGlicmFyeShoZXJlKSAgICAgICANCmxpYnJhcnkod2l0aHIpDQpsaWJyYXJ5KG5hbmlhcikNCmBgYA0KDQojIyBVRk8gc2lnaHRpbmdzDQoNCmBgYHtyfQ0KdWZvX3NpZ2h0aW5ncyAlPiUgDQogIGRwbHlyOjpzbGljZV9zYW1wbGUobiA9IDEwMDApICU+JSANCiAgdmlzX21pc3MoY2x1c3RlciA9IFRSVUUsIHNvcnRfbWlzcyA9IFRSVUUpDQpgYGANCg0KUmVwbGFjaW5nIG1pc3NpbmcgZGF0YSB3aXRoIG1vc3QgZnJlcXVlbnQgZW50cnkgYW5kIHNhdmluZyBjbGVhbmVkIGRhdGENCg0KYGBge3J9DQptb3N0X2NvbW1vbl9kYXlfcGFydCA8LSB1Zm9fc2lnaHRpbmdzICU+JQ0KICBjb3VudChkYXlfcGFydCkgJT4lDQogIGFycmFuZ2UoZGVzYyhuKSkgJT4lDQogIHNsaWNlKDEpICU+JQ0KICBwdWxsKGRheV9wYXJ0KQ0KDQptb3N0X2NvbW1vbl9zaGFwZSA8LSB1Zm9fc2lnaHRpbmdzICU+JQ0KICBjb3VudChzaGFwZSkgJT4lDQogIGFycmFuZ2UoZGVzYyhuKSkgJT4lDQogIHNsaWNlKDEpICU+JQ0KICBwdWxsKHNoYXBlKQ0KDQp1Zm9fY2xlYW4gPC0gdWZvX3NpZ2h0aW5ncyAlPiUNCiAgbXV0YXRlKA0KICAgIGRheV9wYXJ0ID0gaWZlbHNlKGlzLm5hKGRheV9wYXJ0KSwgbW9zdF9jb21tb25fZGF5X3BhcnQsIGRheV9wYXJ0KSwNCiAgICBzaGFwZSA9IGlmZWxzZShpcy5uYShzaGFwZSksIG1vc3RfY29tbW9uX3NoYXBlLCBzaGFwZSkNCiAgKQ0KDQp3cml0ZV9jc3YodWZvX2NsZWFuLCBoZXJlKCJkYXRhIiwgIjIwMjMiLCAiMjAyMy0wNi0yMCIsICJ1Zm9fY2xlYW4uY3N2IikpDQoNCmBgYA0KDQpgYGB7cn0NCnVmb19jbGVhbiAlPiUgDQogIGRwbHlyOjpzbGljZV9zYW1wbGUobiA9IDEwMDApICU+JSANCiAgdmlzX21pc3MoY2x1c3RlciA9IFRSVUUsIHNvcnRfbWlzcyA9IFRSVUUpDQpgYGANCg0KIyMgUGxhY2VzDQoNCmBgYHtyfQ0KcGxhY2VzICU+JSANCiAgZHBseXI6OnNsaWNlX3NhbXBsZShuID0gMTAwMCkgJT4lIA0KICB2aXNfbWlzcyhjbHVzdGVyID0gVFJVRSwgc29ydF9taXNzID0gVFJVRSkNCmBgYA0KDQpSZXBsYWNpbmcgbWlzc2luZyBjaXR5IG5hbWUgd2l0aCBlbXB0eSBzdHJpbmcsIGVsZXZhdGlvbiB3aXRoIG1lYW4gdmFsdWUgYW5kIHNhdmluZyBjbGVhbmVkIGRhdGENCg0KYGBge3J9DQpwbGFjZXNfY2xlYW4gPC0gcGxhY2VzICU+JQ0KICBtdXRhdGUoDQogICAgYWx0ZXJuYXRlX2NpdHlfbmFtZXMgPSBpZmVsc2UoaXMubmEoYWx0ZXJuYXRlX2NpdHlfbmFtZXMpLCAiICIsIGFsdGVybmF0ZV9jaXR5X25hbWVzKQ0KICApDQoNCm1lZGlhbl9lbGV2YXRpb24gPC0gbWVkaWFuKHBsYWNlcyRlbGV2YXRpb25fbSwgbmEucm0gPSBUUlVFKQ0KDQpwbGFjZXNfY2xlYW4gPC0gcGxhY2VzX2NsZWFuICU+JQ0KICBtdXRhdGUoDQogICAgZWxldmF0aW9uX20gPSBpZmVsc2UoaXMubmEoZWxldmF0aW9uX20pLCBtZWRpYW5fZWxldmF0aW9uLCBlbGV2YXRpb25fbSkNCiAgKQ0KDQp3cml0ZV9jc3YocGxhY2VzX2NsZWFuLCBoZXJlKCJkYXRhIiwgIjIwMjMiLCAiMjAyMy0wNi0yMCIsICJwbGFjZXNfY2xlYW4uY3N2IikpDQpgYGANCg0KYGBge3J9DQpwbGFjZXNfY2xlYW4gJT4lIA0KICBkcGx5cjo6c2xpY2Vfc2FtcGxlKG4gPSAxMDAwKSAlPiUgDQogIHZpc19taXNzKGNsdXN0ZXIgPSBUUlVFLCBzb3J0X21pc3MgPSBUUlVFKQ0KYGBgDQoNCiMjIERheSBwYXJ0cyBtYXANCg0KYGBge3J9DQpkYXlfcGFydHNfbWFwICU+JSANCiAgZHBseXI6OnNsaWNlX3NhbXBsZShuID0gMTAwMCkgJT4lIA0KICB2aXNfbWlzcyhjbHVzdGVyID0gVFJVRSwgc29ydF9taXNzID0gVFJVRSkNCmBgYA0KDQpSZXBsYWNpbmcgbWlzc2luZyBkYXRhIHdpdGggbWVhbiB2YWx1ZSBhbmQgc2F2aW5nIGNsZWFuZWQgZGF0YQ0KDQpgYGB7cn0NCmRheV9wYXJ0c19jbGVhbiA8LSBkYXlfcGFydHNfbWFwICU+JQ0KICBtdXRhdGUoDQogICAgYXN0cm9ub21pY2FsX3R3aWxpZ2h0X2JlZ2luID0gaWZlbHNlKA0KICAgICAgaXMubmEoYXN0cm9ub21pY2FsX3R3aWxpZ2h0X2JlZ2luKSwNCiAgICAgIG1lZGlhbihhc3Ryb25vbWljYWxfdHdpbGlnaHRfYmVnaW4sIG5hLnJtID0gVFJVRSksDQogICAgICBhc3Ryb25vbWljYWxfdHdpbGlnaHRfYmVnaW4NCiAgICApLA0KICAgIGFzdHJvbm9taWNhbF90d2lsaWdodF9lbmQgPSBpZmVsc2UoDQogICAgICBpcy5uYShhc3Ryb25vbWljYWxfdHdpbGlnaHRfZW5kKSwNCiAgICAgIG1lZGlhbihhc3Ryb25vbWljYWxfdHdpbGlnaHRfZW5kLCBuYS5ybSA9IFRSVUUpLA0KICAgICAgYXN0cm9ub21pY2FsX3R3aWxpZ2h0X2VuZA0KICAgICkNCiAgKQ0KDQp3cml0ZV9jc3YoZGF5X3BhcnRzX2NsZWFuLCBoZXJlKCJkYXRhIiwgIjIwMjMiLCAiMjAyMy0wNi0yMCIsICJkYXlfcGFydHNfY2xlYW4uY3N2IikpDQpgYGANCg0KYGBge3J9DQpkYXlfcGFydHNfY2xlYW4gJT4lIA0KICBkcGx5cjo6c2xpY2Vfc2FtcGxlKG4gPSAxMDAwKSAlPiUgDQogIHZpc19taXNzKGNsdXN0ZXIgPSBUUlVFLCBzb3J0X21pc3MgPSBUUlVFKQ0KYGBgDQoNCiMgQWRqdXN0IHRoZSBkYXRhIGZvcm1hdCB0byBtZWV0IHRoZSByZXF1aXJlbWVudHMgb2YgeW91ciBhbmFseXNpcw0KDQpgYGB7cn0NCg0KdWZvX21vZGVsX2RhdGEgPC0gdWZvX2NsZWFuICU+JQ0KICBmaWx0ZXIoIWlzLm5hKHNoYXBlKSwgIWlzLm5hKHJlcG9ydGVkX2R1cmF0aW9uKSwgIWlzLm5hKHN1bW1hcnkpKQ0KDQoNCnBsYWNlc19tb2RlbF9kYXRhIDwtIHBsYWNlc19jbGVhbiAlPiUNCiAgZmlsdGVyKCFpcy5uYShhbHRlcm5hdGVfY2l0eV9uYW1lcykpDQoNCmBgYA0KDQpgYGB7cn0NCmdsaW1wc2UodWZvX21vZGVsX2RhdGEpDQpnbGltcHNlKHBsYWNlc19tb2RlbF9kYXRhKQ0KZ2xpbXBzZShkYXlfcGFydHNfY2xlYW4pDQpgYGANCg0KYGBge3J9DQp3cml0ZV9jc3YodWZvX21vZGVsX2RhdGEsIGhlcmUoImRhdGEiLCAiMjAyMyIsICIyMDIzLTA2LTIwIiwgInVmb19tb2RlbF9kYXRhLmNzdiIpKQ0Kd3JpdGVfY3N2KHBsYWNlc19tb2RlbF9kYXRhLCBoZXJlKCJkYXRhIiwgIjIwMjMiLCAiMjAyMy0wNi0yMCIsICJwbGFjZXNfbW9kZWxfZGF0YS5jc3YiKSkNCmBgYA0KDQojIEFkZCBuZXcgY29sdW1ucyB0byBlYWNoIGRhdGFmcmFtZQ0KDQpgYGB7cn0NCmxpYnJhcnkobHVicmlkYXRlKQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkoaG1zKQ0KYGBgDQoNCkFkZGluZyBuZXcgY29sdW1ucyB0byAic2lnaHRpbmdzIiBkYXRhZnJhbWUNCg0KYGBge3J9DQp1Zm9fbW9kZWxfZGF0YV9tdXRhdGVkIDwtIHVmb19tb2RlbF9kYXRhICU+JQ0KICBtdXRhdGUoDQogICAgeWVhciA9IHllYXIocmVwb3J0ZWRfZGF0ZV90aW1lKSwNCiAgICBtb250aCA9IG1vbnRoKHJlcG9ydGVkX2RhdGVfdGltZSksDQogICAgd2Vla2RheSA9IHdkYXkocmVwb3J0ZWRfZGF0ZV90aW1lLCBsYWJlbCA9IFRSVUUsIGFiYnIgPSBGQUxTRSwgbG9jYWxlID0gIkMiKSwNCiAgICBpc193ZWVrZW5kID0gd2Vla2RheSAlaW4lIGMoIlNhdCIsICJTdW4iKSwNCiAgICBjb3VudHJ5X3VwcGVyID0gdG91cHBlcihjb3VudHJ5X2NvZGUpLA0KICAgIHJlcG9ydF9ob3VyID0gaG91cihyZXBvcnRlZF9kYXRlX3RpbWUpLA0KICAgIGNpdHlfc3RhdGUgPSBwYXN0ZShjaXR5LCBzdGF0ZSwgc2VwID0gIiwgIiksDQogICAgcmVwb3J0X2RlbGF5X2RheXMgPSBhcy5udW1lcmljKGRpZmZ0aW1lKHBvc3RlZF9kYXRlLCBhcy5EYXRlKHJlcG9ydGVkX2RhdGVfdGltZSksIHVuaXRzID0gImRheXMiKSkNCiAgKQ0KDQp1Zm9fbW9kZWxfZGF0YV9tdXRhdGVkDQpgYGANCg0KLSAgIGB5ZWFyYDogRXh0cmFjdHMgdGhlIHllYXIgZnJvbSB0aGUgYHJlcG9ydGVkX2RhdGVfdGltZWAuDQotICAgYG1vbnRoYDogRXh0cmFjdHMgdGhlIG1vbnRoICgx4oCTMTIpIGZyb20gdGhlIHJlcG9ydCB0aW1lLXN0YW1wLg0KLSAgIGB3ZWVrZGF5YDogUmV0dXJucyB0aGUgd2Vla2RheSBuYW1lIGZyb20gdGhlIGRhdGUuDQotICAgYGlzX3dlZWtlbmRgOiBMb2dpY2FsIGNvbHVtbjogYFRSVUVgIGlmIHRoZSBkYXkgaXMgU2F0dXJkYXkgb3IgU3VuZGF5LCBgRkFMU0VgIG90aGVyd2lzZS4NCi0gICBgY291bnRyeV91cHBlcmA6IENvbnZlcnRzIHRoZSBgY291bnRyeV9jb2RlYCB0byB1cHBlcmNhc2UuDQotICAgYHJlcG9ydF9ob3VyYDogRXh0cmFjdHMgdGhlIGhvdXIgKDDigJMyMykgZnJvbSB0aGUgcmVwb3J0IHRpbWUtc3RhbXAuDQotICAgYGNpdHlfc3RhdGVgOiBDb25jYXRlbmF0ZXMgYGNpdHlgIGFuZCBgc3RhdGVgIGludG8gYSBzaW5nbGUgc3RyaW5nLg0KLSAgIGByZXBvcnRfZGVsYXlfZGF5c2A6IENhbGN1bGF0ZXMgdGhlIGRlbGF5IGluIGRheXMgYmV0d2VlbiB3aGVuIHRoZSBldmVudCB3YXMgcmVwb3J0ZWQgYW5kIHdoZW4gaXQgd2FzIHBvc3RlZC4NCg0KQWRkaW5nIG5ldyBjb2x1bW5zIHRvICJwbGFjZXMiIGRhdGFmcmFtZQ0KDQpgYGB7cn0NCnBsYWNlc19tb2RlbF9kYXRhX211dGF0ZWQgPC0gcGxhY2VzX21vZGVsX2RhdGEgJT4lDQogIG11dGF0ZSgNCiAgICBjaXR5X3N0YXRlID0gcGFzdGUoY2l0eSwgc3RhdGUsIHNlcCA9ICIsICIpLA0KICAgIGlzX3VzID0gY291bnRyeV9jb2RlID09ICJVUyIsDQogICAgcG9wdWxhdGlvbl9sb2cgPSBsb2cxcChwb3B1bGF0aW9uKSwNCiAgICBoZW1pc3BoZXJlID0gaWZlbHNlKGxhdGl0dWRlID49IDAsICJOb3J0aGVybiIsICJTb3V0aGVybiIpLA0KICAgIGlzX2NvYXN0YWwgPSBhYnMobG9uZ2l0dWRlKSA8IDgwIHwgYWJzKGxvbmdpdHVkZSkgPiAxMjAsDQogICAgcG9wX2NhdGVnb3J5ID0gY2FzZV93aGVuKA0KICAgICAgcG9wdWxhdGlvbiA8IDEwMDAwIH4gInNtYWxsIiwNCiAgICAgIHBvcHVsYXRpb24gPCAxMDAwMDAgfiAibWVkaXVtIiwNCiAgICAgIFRSVUUgfiAibGFyZ2UiDQogICAgKSwNCiAgICBlbGV2YXRpb25fY2F0ZWdvcnkgPSBjYXNlX3doZW4oDQogICAgICBpcy5uYShlbGV2YXRpb25fbSkgfiAidW5rbm93biIsDQogICAgICBlbGV2YXRpb25fbSA8IDEwMCB+ICJsb3ciLA0KICAgICAgZWxldmF0aW9uX20gPCA1MDAgfiAibWVkaXVtIiwNCiAgICAgIFRSVUUgfiAiaGlnaCINCiAgICApLA0KICAgIG5hbWVfbGVuZ3RoID0gbmNoYXIoY2l0eSksDQogICAgdGltZXpvbmVfYXJlYSA9IHNhcHBseShzdHJzcGxpdCh0aW1lem9uZSwgIi8iKSwgYFtgLCAyKQ0KICApDQoNCnBsYWNlc19tb2RlbF9kYXRhX211dGF0ZWQNCmBgYA0KDQotICAgYGNpdHlfc3RhdGVgOiBDb21iaW5lcyBgY2l0eWAgYW5kIGBzdGF0ZWAgaW50byBhIHNpbmdsZSBzdHJpbmcuDQotICAgYGlzX3VzYDogTG9naWNhbCB2YWx1ZTogYFRSVUVgIGlmIHRoZSBsb2NhdGlvbiBpcyBpbiB0aGUgVW5pdGVkIFN0YXRlcyBlbHNlIGBGQUxTRWAuDQotICAgYHBvcHVsYXRpb25fbG9nYDogTG9nLXRyYW5zZm9ybWVkIHBvcHVsYXRpb24uDQotICAgYGhlbWlzcGhlcmVgOiBgIk5vcnRoZXJuImAgaWYgbGF0aXR1ZGUgaXMg4omlIDAsIGAiU291dGhlcm4iYCBvdGhlcndpc2UuDQotICAgYGlzX2NvYXN0YWxgOiBMb2dpY2FsOiBgVFJVRWAgaWYgbG9uZ2l0dWRlIGlzIG91dHNpZGUgdGhlIHJhbmdlIFs4MCwgMTIwXSBpbiBhYnNvbHV0ZSB2YWx1ZSDigJQgYSByb3VnaCBjb2FzdGFsIHByb3h5Lg0KLSAgIGBwb3BfY2F0ZWdvcnlgOiBDYXRlZ29yaXplcyBwbGFjZXMgYmFzZWQgb24gcG9wdWxhdGlvbjogYCJzbWFsbCJgLCBgIm1lZGl1bSJgLCBvciBgImxhcmdlImAuDQotICAgYGVsZXZhdGlvbl9jYXRlZ29yeWA6IENsYXNzaWZpZXMgZWxldmF0aW9uOiBgImxvdyJgIChcPDEwMCBtKSwgYCJtZWRpdW0iYCAoXDw1MDAgbSksIGAiaGlnaCJgICjiiaU1MDAgbSksIG9yIGAidW5rbm93biJgIGlmIE5BLg0KLSAgIGBuYW1lX2xlbmd0aGA6IFRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyBpbiB0aGUgY2l0eSBuYW1lLg0KLSAgIGB0aW1lem9uZV9hcmVhYDogRXh0cmFjdHMgdGhlIHNlY29uZCBwYXJ0IG9mIHRoZSB0aW1lem9uZSBzdHJpbmcuDQoNCkFkZGluZyBuZXcgY29sdW1ucyB0byAiZGF5IHBhcnRzIiBkYXRhZnJhbWUNCg0KYGBge3J9DQpkYXlfcGFydHNfbW9kZWxfbXV0YXRlZCA8LSBkYXlfcGFydHNfY2xlYW4gJT4lDQogIG11dGF0ZSgNCiAgICBkYXlsaWdodF9kdXJhdGlvbiA9IGFzLm51bWVyaWMoc3Vuc2V0IC0gc3VucmlzZSwgdW5pdHMgPSAic2VjcyIpLA0KICAgIGlzX25vcnRoZXJuX2hlbWlzcGhlcmUgPSByb3VuZGVkX2xhdCA+PSAwLA0KICAgIHN1bnJpc2VfaG91ciA9IGhvdXIoc3VucmlzZSksDQogICAgc3Vuc2V0X2hvdXIgPSBob3VyKHN1bnNldCksDQogICAgaXNfZGF5X3Nob3J0ID0gZGF5bGlnaHRfZHVyYXRpb24gPCAzNjAwMCwgIyBtbmllaiBuacW8IDEwaA0KICAgIHR3aWxpZ2h0X2R1cmF0aW9uID0gYXMubnVtZXJpYyhhc3Ryb25vbWljYWxfdHdpbGlnaHRfZW5kIC0gYXN0cm9ub21pY2FsX3R3aWxpZ2h0X2JlZ2luLCB1bml0cyA9ICJzZWNzIiksDQogICAgaXNfbG9uZ190d2lsaWdodCA9IHR3aWxpZ2h0X2R1cmF0aW9uID4gNTQwMCwgIyAxLjVoDQogICAgc3VucmlzZV9taW51dGVzID0gaG91cihzdW5yaXNlKSAqIDYwICsgbWludXRlKHN1bnJpc2UpLA0KICAgIHNvbGFyX25vb25fbWludXRlcyA9IGhvdXIoc29sYXJfbm9vbikgKiA2MCArIG1pbnV0ZShzb2xhcl9ub29uKSwNCiAgICBzdW5zZXRfbWludXRlcyA9IGhvdXIoc3Vuc2V0KSAqIDYwICsgbWludXRlKHN1bnNldCkNCiAgKQ0KDQpkYXlfcGFydHNfbW9kZWxfbXV0YXRlZA0KYGBgDQotIGBkYXlsaWdodF9kdXJhdGlvbmA6IFRoZSBsZW5ndGggb2YgdGhlIGRheSBpbiBzZWNvbmRzIOKAlCBkaWZmZXJlbmNlIGJldHdlZW4gYHN1bnNldGAgYW5kIGBzdW5yaXNlYC4NCi0gYGlzX25vcnRoZXJuX2hlbWlzcGhlcmVgOiBMb2dpY2FsOiBgVFJVRWAgaWYgdGhlIGxvY2F0aW9uIGlzIGluIHRoZSBOb3J0aGVybiBIZW1pc3BoZXJlLiANCi0gYHN1bnJpc2VfaG91cmA6IFRoZSBob3VyICgw4oCTMjMpIHdoZW4gdGhlIHN1biByaXNlcy4NCi0gYHN1bnNldF9ob3VyYDogCVRoZSBob3VyICgw4oCTMjMpIHdoZW4gdGhlIHN1biBzZXRzLg0KLSBgaXNfZGF5X3Nob3J0YDogTG9naWNhbDogYFRSVUVgIGlmIHRoZSBkYXkgaXMgc2hvcnRlciB0aGFuIDEwIGhvdXJzIA0KLSBgdHdpbGlnaHRfZHVyYXRpb25gOiBEdXJhdGlvbiBvZiBhc3Ryb25vbWljYWwgdHdpbGlnaHQgaW4gc2Vjb25kcyDigJQgdGltZSBiZXR3ZWVuIGBhc3Ryb25vbWljYWxfdHdpbGlnaHRfYmVnaW5gIGFuZCBgZW5kYC4NCi0gYGlzX2xvbmdfdHdpbGlnaHRgOiBMb2dpY2FsOiBgVFJVRWAgaWYgdHdpbGlnaHQgZHVyYXRpb24gaXMgbG9uZ2VyIHRoYW4gMS41IGhvdXJzDQotIGBzdW5yaXNlX21pbnV0ZXNgOiBTdW5yaXNlIHRpbWUgaW4gdG90YWwgbWludXRlcyBmcm9tIG1pZG5pZ2h0Lg0KLSBgc29sYXJfbm9vbl9taW51dGVzYDogU29sYXIgbm9vbiB0aW1lIGluIG1pbnV0ZXMgZnJvbSBtaWRuaWdodC4NCi0gYHN1bnNldF9taW51dGVzYDogU3Vuc2V0IHRpbWUgaW4gbWludXRlcyBmcm9tIG1pZG5pZ2h0Lg0KDQpgYGB7cn0NCmdsaW1wc2UodWZvX21vZGVsX2RhdGFfbXV0YXRlZCkNCmdsaW1wc2UocGxhY2VzX21vZGVsX2RhdGFfbXV0YXRlZCkNCmdsaW1wc2UoZGF5X3BhcnRzX2NsZWFuKQ0KYGBgDQoNCiMgRXhwbG9yZSBkYXRhIHdpdGggY2hhcnRzDQoNCmBgYHtyfQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkoc2YpDQpsaWJyYXJ5KHJuYXR1cmFsZWFydGgpDQpsaWJyYXJ5KHJuYXR1cmFsZWFydGhkYXRhKQ0KYGBgDQoNCk51bWJlciBvZiBzaWdodGluZ3MgcGVyIGRheQ0KDQpgYGB7cn0NCnVmb19tb2RlbF9kYXRhX211dGF0ZWQgJT4lDQogIGNvdW50KGRhdGUgPSBhcy5EYXRlKHJlcG9ydGVkX2RhdGVfdGltZSkpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBkYXRlLCB5ID0gbikpICsNCiAgZ2VvbV9saW5lKGNvbG9yID0gInN0ZWVsYmx1ZSIpICsNCiAgbGFicyh0aXRsZSA9ICJOdW1iZXIgb2Ygc2lnaHRpbmdzIHBlciBkYXkiLCB4ID0gIkRhdGUiLCB5ID0gIk51bWJlciBvZiBzaWdodGluZ3MiKQ0KYGBgDQoNCk51bWJlciBvZiBzaWdodGluZ3MgZGVwZW5kaW5nIG9uIHRoZSBkYXkgb2YgdGhlIHdlZWsNCg0KYGBge3J9DQp1Zm9fbW9kZWxfZGF0YV9tdXRhdGVkICU+JQ0KICBjb3VudCh3ZWVrZGF5KSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gd2Vla2RheSwgeSA9IG4pKSArDQogIGdlb21fY29sKGZpbGwgPSAib3JhbmdlIikgKw0KICBsYWJzKHRpdGxlID0gIlNpZ2h0aW5ncyBkZXBlbmRpbmcgb24gdGhlIGRheSBvZiB0aGUgd2VlayIsIHggPSAiRGF5IG9mIHRoZSB3ZWVrIiwgeSA9ICJOdW1iZXIgb2Ygc2lnaHRpbmdzIikNCmBgYA0KDQpIb3VybHkgZGlzdHJpYnV0aW9uIG9mIHNpZ2h0aW5ncw0KDQpgYGB7cn0NCnVmb19tb2RlbF9kYXRhX211dGF0ZWQgJT4lDQogIG11dGF0ZShob3VyID0gaG91cihyZXBvcnRlZF9kYXRlX3RpbWUpKSAlPiUNCiAgY291bnQoaG91cikgJT4lDQogIGdncGxvdChhZXMoeCA9IGhvdXIsIHkgPSBuKSkgKw0KICBnZW9tX2NvbChmaWxsID0gInB1cnBsZSIpICsNCiAgbGFicyh0aXRsZSA9ICJIb3VybHkgZGlzdHJpYnV0aW9uIG9mIHNpZ2h0aW5ncyIsIHggPSAiSG91ciBvZiB0aGUgZGF5IiwgeSA9ICJOdW1iZXIgb2Ygc2lnaHRpbmdzIikNCmBgYA0KDQpIZWF0bWFwOiBkYXkgb2YgdGhlIHdlZWsgdnMgaG91ciBvZiB0aGUgZGF5DQoNCmBgYHtyfQ0KdWZvX21vZGVsX2RhdGFfbXV0YXRlZCAlPiUNCiAgbXV0YXRlKA0KICAgIGhvdXIgPSBob3VyKHJlcG9ydGVkX2RhdGVfdGltZSksDQogICAgd2Vla2RheSA9IGZjdF9yZWxldmVsKHdlZWtkYXksIGMoIk1vbiIsICJUdWUiLCAiV2VkIiwgIlRodSIsICJGcmkiLCAiU2F0IiwgIlN1biIpKQ0KICApICU+JQ0KICBjb3VudCh3ZWVrZGF5LCBob3VyKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gaG91ciwgeSA9IHdlZWtkYXksIGZpbGwgPSBuKSkgKw0KICBnZW9tX3RpbGUoY29sb3IgPSAid2hpdGUiKSArDQogIHNjYWxlX2ZpbGxfdmlyaWRpc19jKCkgKw0KICBsYWJzKHRpdGxlID0gIkhlYXRtYXA6IGRheSBvZiB0aGUgd2VlayB2cyBob3VyIG9mIHRoZSBkYXkiLCB4ID0gIkhvdXIgb2YgdGhlIGRheSIsIHkgPSAiRGF5IG9mIHRoZSB3ZWVrIiwgZmlsbCA9ICJOdW1iZXIgb2Ygc2lnaHRpbmdzIikNCg0KYGBgDQoNCmBgYHtyfQ0KdWZvX21vZGVsX2RhdGFfbXV0YXRlZCAlPiUNCiAgbXV0YXRlKGltYWdlX3N0YXR1cyA9IGlmZWxzZShoYXNfaW1hZ2VzLCAiSGFzIGFuIGltYWdlIiwgIkhhcyBubyBpbWFnZSIpKSAlPiUNCiAgY291bnQoaW1hZ2Vfc3RhdHVzKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gIiIsIHkgPSBuLCBmaWxsID0gaW1hZ2Vfc3RhdHVzKSkgKw0KICBnZW9tX2NvbCh3aWR0aCA9IDEpICsNCiAgY29vcmRfcG9sYXIodGhldGEgPSAieSIpICsNCiAgbGFicyh0aXRsZSA9ICJTaWdodGlucyB3aXRoIGltYWdlcyB2cyBubyBpbWFnZSIsIGZpbGwgPSAiSW1hZ2UgZXhpc3RlbmNlIikgKw0KICB0aGVtZV92b2lkKCkgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCJIYXMgYW4gaW1hZ2UiID0gIiM2NkJCNkEiLCAiSGFzIG5vIGltYWdlIiA9ICIjRUY1MzUwIikpDQpgYGANCg0KTWFraW5nIHN1cmUgaWYgYWJvdmUgcGllY2hhcnQgaXMgY29ycmVjdA0KDQpgYGB7cn0NCnN1bSh1Zm9fbW9kZWxfZGF0YV9tdXRhdGVkJGhhc19pbWFnZXMgIT0gRkFMU0UsIG5hLnJtID0gVFJVRSkNCmBgYA0KDQpOdW1iZXIgb2Ygc2lnaHRpbmdzIHBlciBzaGFwZQ0KDQpgYGB7cn0NCnVmb19tb2RlbF9kYXRhX211dGF0ZWQgJT4lDQogIGNvdW50KHNoYXBlKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gcmVvcmRlcihzaGFwZSwgbiksIHkgPSBuKSkgKw0KICBnZW9tX2NvbChmaWxsID0gInNreWJsdWUiKSArDQogIGNvb3JkX2ZsaXAoKSArDQogIGxhYnModGl0bGUgPSAiTnVtYmVyIG9mIHNpZ2h0aW5ncyBwZXIgc2hhcGUiLCB4ID0gIlNoYXBlIiwgeSA9ICJOdW1iZXIgb2Ygc2lnaHRpbmdzIikNCmBgYA0KDQpOdW1iZXIgb2Ygc2lnaHRpbmdzIHBlciBjb3VudHJ5DQoNCmBgYHtyfQ0KdWZvX21vZGVsX2RhdGFfbXV0YXRlZCAlPiUNCiAgY291bnQoY291bnRyeV9jb2RlKSAlPiUNCiAgZmlsdGVyKG4gPj0gMTAwKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gcmVvcmRlcihjb3VudHJ5X2NvZGUsIG4pLCB5ID0gbikpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIGZpbGwgPSAic2t5Ymx1ZSIpICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJOdW1iZXIgb2Ygc2lnaHRpbmdzIHBlciBjb3VudHJ5IiwNCiAgICB4ID0gIkNvdW50cnkgY29kZSIsDQogICAgeSA9ICJOdW1iZXIgb2Ygc2lnaHRpbmdzIg0KICApICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkNCmBgYA0KDQpEZW5zaXR5IG1hcCBvZiBzaWdodGluZ3MNCg0KYGBge3J9DQp3b3JsZCA8LSBuZV9jb3VudHJpZXMoc2NhbGUgPSAibWVkaXVtIiwgcmV0dXJuY2xhc3MgPSAic2YiKQ0KDQpwbGFjZXNfY2xlYW4gJT4lDQogIGZpbHRlcighaXMubmEobGF0aXR1ZGUpLCAhaXMubmEobG9uZ2l0dWRlKSkgJT4lDQogIG11dGF0ZSgNCiAgICBwb3BfY2F0ZWdvcnkgPSBjYXNlX3doZW4oDQogICAgICBwb3B1bGF0aW9uIDwgMTAwMDAgIH4gInNtYWxsIiwNCiAgICAgIHBvcHVsYXRpb24gPCAxMDAwMDAgfiAibWVkaXVtIiwNCiAgICAgIFRSVUUgICAgICAgICAgICAgICAgfiAibGFyZ2UiDQogICAgKQ0KICApICU+JQ0KICBnZ3Bsb3QoKSArDQogIGdlb21fc2YoZGF0YSA9IHdvcmxkLCBmaWxsID0gImxpZ2h0Z3JheSIsIGNvbG9yID0gImJsYWNrIikgKyAgIyBEb2RhamVteSBtYXDEmQ0KICBnZW9tX3BvaW50KGFlcygNCiAgICB4ID0gbG9uZ2l0dWRlLCB5ID0gbGF0aXR1ZGUsDQogICAgc2l6ZSA9IHBvcHVsYXRpb24sIGNvbG9yID0gcG9wX2NhdGVnb3J5DQogICksIGFscGhhID0gMC42KSArDQogIHNjYWxlX3NpemUocmFuZ2UgPSBjKDEsIDYpLCBndWlkZSA9ICJub25lIikgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIkNpdGllcyB3aXRoIFVGTyBzaWdodGluZ3MiLA0KICAgIHN1YnRpdGxlID0gIlBvaW50IHNpemUgfiBwb3B1bGF0aW9uLCBjb2xvciB+IHBvcHVsYXRpb24gY2F0ZWdvcnkiLA0KICAgIHggPSAiTGF0aXR1ZGUiLA0KICAgIHkgPSAiQWx0aXR1ZGUiLA0KICAgIGNvbG9yID0gIlBvcHVsYXRpb24gY2F0ZWdvcnkiDQogICkgKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0K